home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 February: Tool Chest / Dev.CD Feb 95 / Dev.CD Feb 95.toast / Tool Chest / QuickDraw GX / QuickDraw GX Info / QuickDraw GX Interfaces / Interfaces & Libraries / graphics libraries / transferMode library.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-30  |  9.6 KB  |  334 lines  |  [TEXT/MPS ]

  1. /* graphics libraries:
  2.     transfer mode library
  3.     by Cary Clark, Georgiann Delaney, Michael Fairman, Dave Good, Josh Horwich, Robert Johnson, Keith McGreggor, Oliver Steele, David Van Brink, Chris Yerga
  4.     Copyright 1987 - 1993 Apple Computer, Inc.  All rights reserved.    */
  5.  
  6.     #include <Memory.h>
  7. #include "graphics libraries.h"
  8.  
  9. /*
  10.   * Routines
  11.   */
  12.  
  13. static void InitColorMatrix(Fixed m[5][4])
  14. {
  15.     register Fixed *x;
  16.     register short i;
  17.  
  18.     x = &m[0][0];
  19.     for(i = 19; i>=0; i--)
  20.         *x++ = 0;
  21.     m[0][0] = m[1][1] = m[2][2] = m[3][3] = fixed1;           /* Identity matrix, for cleanliness */
  22. }
  23.  
  24. /*
  25.   * Initialize all fields of a transfermode record
  26.   * to a very reasonable rgb copy mode.
  27.   */
  28. void InitTransferMode(gxTransferMode *mode)
  29. {
  30.     NilParamReturn(mode);
  31.     SetCommonTransfer(mode,gxCopyMode,0,nil);
  32. }   
  33.  
  34. gxTransferMode *SetCommonTransfer(register gxTransferMode *mode,  commonTransferMode type, unsigned short opValue, const gxColor *opColor)
  35. {
  36.     register gxTransferComponent *component;
  37.     register short i;
  38.     gxColor oColor;
  39.  
  40.     NilParamReturnNil(mode);
  41.  
  42.     if(opColor)
  43.         {
  44.         oColor = *opColor;
  45.         GXConvertColor(&oColor,gxRGBASpace, nil, nil);
  46.         }
  47.     else
  48.         {
  49.         oColor.space = gxRGBASpace;
  50.         oColor.element.rgba.red =
  51.         oColor.element.rgba.green =
  52.         oColor.element.rgba.blue = opValue;
  53.         oColor.element.rgba.alpha = 65535;
  54.         }
  55.  
  56.     if(type >= gxOverMode && type <= gxFadeMode)
  57.         mode->space = gxRGBASpace;
  58.     else
  59.         mode->space = gxRGBSpace;
  60.  
  61.     mode->flags = 0;
  62.     mode->set = nil;
  63.     mode->profile = nil;
  64.  
  65.     component = &mode->component[0];
  66.     InitColorMatrix(mode->sourceMatrix);
  67.     InitColorMatrix(mode->deviceMatrix);
  68.     InitColorMatrix(mode->resultMatrix);
  69.  
  70.     component->mode = type;
  71.     component->flags = 0;
  72.  
  73.     component->sourceMinimum = component->deviceMinimum = component->clampMinimum = 0;
  74.     component->sourceMaximum = component->deviceMaximum = component->clampMaximum = 65535;
  75.  
  76.     for(i = 3; i>=0; i--)
  77.         {
  78.         component = &mode->component[i];
  79.  
  80.         *component = mode->component[0];
  81.         component->operand = (&oColor.element.rgb.red)[i];
  82.  
  83.         switch(type)
  84.             {
  85.             case gxHighlightMode:
  86.                 if(!opColor)                    /* if no opColor passed, use lomem RGBHilite    */
  87.                     component->operand = ((short *)0xDA0)[i];
  88.                 break;
  89.             case gxOverMode:                      /* use it like a real alpha mode                */
  90.                 if(i==3)
  91.                     component->mode = gxRampOrMode;
  92.                 break;
  93.             case gxAtopMode:                      /* use it like a real alpha mode                */
  94.                 if(i==3)
  95.                     {
  96.                     component->flags |= gxReverseComponent;
  97.                     component->mode = gxCopyMode; /* result alpha = device alpha      */
  98.                     }
  99.                 break;
  100.             case gxExcludeMode:                   /* use it like a real alpha mode                */
  101.                 if(i==3)
  102.                     component->mode = gxRampXorMode;
  103.                 break;
  104.             case gxFadeMode:
  105.                 if(i==3)
  106.                     component->mode = gxAddMode;
  107.                 break;
  108.             case commonAddOverMode:
  109.                 component->mode = gxAddMode;
  110.                 component->flags |= gxOverResultComponent;
  111.                 break;
  112.             case commonSubtractOverMode:
  113.                 component->mode = gxAddMode;
  114.                 component->flags |= gxOverResultComponent;
  115.                 mode->sourceMatrix[i][i] = -fixed1;
  116.                 break;
  117.             case commonSubtractPinMode:
  118.                 component->mode = gxAddMode;
  119.                 mode->sourceMatrix[i][i] = -fixed1;
  120.                 break;
  121.             case commonTransparentMode:         /* the opColor specifies which gxColor to avoid from source   */
  122.                 component->mode = gxCopyMode;
  123.                 mode->flags |= gxRejectSourceTransfer;
  124.                 if(opColor)
  125.                     {
  126.                     component->sourceMinimum =
  127.                     component->sourceMaximum = (&oColor.element.rgb.red)[i];
  128.                     }
  129.                 else                            /* default is avoid drawing white */
  130.                     {
  131.                     component->sourceMinimum =
  132.                     component->sourceMaximum = 65535;
  133.                     }
  134.                 break;
  135.             case commonInMode:
  136.                 if(i==3)
  137.                     component->mode = gxRampAndMode;
  138.                 else
  139.                     component->mode = gxCopyMode;
  140.                 break;
  141.             case commonOutMode:
  142.                 if(i==3)
  143.                     {
  144.                     component->mode = gxRampAndMode;
  145.                     mode->deviceMatrix[3][3] = -fixed1;
  146.                     mode->deviceMatrix[4][3] = 65535;
  147.                     }
  148.                 else
  149.                     component->mode = gxCopyMode;
  150.                 break;
  151.  
  152.  
  153.             }
  154.  
  155.         }
  156.  
  157.     return mode;
  158. }
  159.  
  160. void SetInkCommonTransfer(gxInk source, commonTransferMode type)
  161. {
  162.     gxTransferMode mode;
  163.     
  164.     NilInkReturn(source);
  165.     SetCommonTransfer(&mode, type,32768,nil);
  166.     GXSetInkTransfer(source, &mode);
  167. }
  168.  
  169. void SetShapeCommonTransfer(gxShape source, commonTransferMode type)
  170. {
  171.     gxTransferMode mode;
  172.     
  173.     NilShapeReturn(source);
  174.     SetCommonTransfer(&mode, type,32768,nil);
  175.     GXSetShapeTransfer(source, &mode);
  176. }
  177.  
  178. commonTransferMode GetShapeCommonTransfer(gxShape source)
  179. {
  180.     gxTransferMode mode;
  181.     
  182.     NilShapeReturnNil(source);
  183.     GXGetShapeTransfer(source, &mode);
  184.     return mode.component[0].mode;
  185. }
  186.  
  187. commonTransferMode GetInkCommonTransfer(gxInk source)
  188. {
  189.     gxTransferMode mode;
  190.     
  191.     NilInkReturnNil(source);
  192.     GXGetInkTransfer(source, &mode);
  193.     return mode.component[0].mode;
  194. }
  195.  
  196. gxColor *TransmogrifyColor(gxColor *dstColor, const gxColor *srcColor, const gxTransferMode *mode)
  197. {
  198.     gxInk tempInk = GXNewInk();
  199.     
  200.     GXSetInkColor(tempInk,srcColor);
  201.     GXSetInkTransfer(tempInk,mode);
  202.     GXCombineColor(dstColor, tempInk);
  203.     GXDisposeInk(tempInk);
  204.     return dstColor;
  205. }
  206.  
  207. /* Given an gxInk and a device, set's up the gxInk's mode so that drawing over the background gxColor leaves
  208.   * the result gxColor. Also sets up the gxTransferMode gxColorSpace etc. so that the fast case is taken.
  209.   */
  210. void SetInkFastXorTransfer(gxInk inky, gxViewDevice destDevice, gxViewPort destViewPort, gxColor *background, gxColor *result)
  211. {
  212.     gxShape deviceBitsShape;
  213.     gxBitmap deviceBits;
  214.     gxTransferMode fastMode;
  215.     gxColor inkColor;
  216.  
  217.     gxColor localBackground;
  218.     gxColor localResult;
  219.  
  220.     localBackground.space = gxRGBSpace;
  221.     localBackground.profile = nil;
  222.     localBackground.element.rgb.red = 0xFFFF;
  223.     localBackground.element.rgb.green = 0xFFFF;
  224.     localBackground.element.rgb.blue = 0xFFFF;
  225.     
  226.     localResult.space = gxRGBSpace;
  227.     localResult.profile = nil;
  228.     localResult.element.rgb.red = 0;
  229.     localResult.element.rgb.green = 0;
  230.     localResult.element.rgb.blue = 0;
  231.     
  232.     if (background)
  233.         localBackground = *background;
  234.     if (result)
  235.         localResult = *result;
  236.       
  237.     deviceBitsShape = GXGetViewDeviceBitmap(destDevice);
  238.     GXGetBitmap(deviceBitsShape, &deviceBits, nil);
  239.     
  240.      if (destViewPort && (GXGetViewPortAttributes(destViewPort) & gxEnableMatchPort) == 0) {
  241.          localBackground.profile = deviceBits.profile;    /* if drawing through the viewport will disable color matching, we */
  242.          localResult.profile = deviceBits.profile;        /* want to do the same thing for our GXConvertColor calls. */
  243.      }
  244.         
  245.     InitTransferMode(&fastMode);
  246.     fastMode.flags |= gxSingleComponentTransfer;
  247.     fastMode.component[0].mode = gxXorMode;
  248.     if ((fastMode.space = deviceBits.space) == gxIndexedSpace) {
  249.         fastMode.set = deviceBits.set;
  250.         GXConvertColor(&localBackground, gxIndexedSpace, deviceBits.set, deviceBits.profile);
  251.         GXConvertColor(&localResult, gxIndexedSpace, deviceBits.set, deviceBits.profile);
  252.         if (localBackground.element.indexed.index == localResult.element.indexed.index) {
  253.         
  254.                 /* OK, the two colors map into the same index. We will instead use black and white */
  255.         localBackground.space = gxRGBSpace;
  256.         localBackground.profile = nil;
  257.         localBackground.element.rgb.red = 0xFFFF;
  258.         localBackground.element.rgb.green = 0xFFFF;
  259.         localBackground.element.rgb.blue = 0xFFFF;
  260.             
  261.         localResult.space = gxRGBSpace;
  262.         localResult.profile = nil;
  263.         localResult.element.rgb.red = 0;
  264.         localResult.element.rgb.green = 0;
  265.         localResult.element.rgb.blue = 0;
  266.             
  267.             GXConvertColor(&localBackground, gxIndexedSpace, deviceBits.set, deviceBits.profile);
  268.             GXConvertColor(&localResult, gxIndexedSpace, deviceBits.set, deviceBits.profile);
  269.         
  270.         if (localBackground.element.indexed.index == localResult.element.indexed.index) {
  271.  
  272.                     if (localResult.element.indexed.index > 1)
  273.                         --localResult.element.indexed.index;
  274.                     else
  275.                         ++localResult.element.indexed.index;     /* This assumes that gxColorSet has at least 2 colors */
  276.         }
  277.         }
  278.         inkColor.space = gxIndexedSpace;
  279.         inkColor.profile = deviceBits.profile;
  280.         inkColor.element.indexed.set = deviceBits.set;
  281.         inkColor.element.indexed.index = ((localBackground.element.indexed.index - 1) ^
  282.                                 (localResult.element.indexed.index - 1)) + 1;
  283.     } else {
  284.         fastMode.space = gxRGBSpace;
  285.         GXConvertColor(&localBackground, gxRGBSpace, nil, deviceBits.profile);
  286.         GXConvertColor(&localResult, gxRGBSpace, nil, deviceBits.profile);
  287.         inkColor.space = gxRGBSpace;
  288.         inkColor.profile = deviceBits.profile;
  289.         inkColor.element.rgb.red = localBackground.element.rgb.red ^ localResult.element.rgb.red;
  290.         inkColor.element.rgb.green = localBackground.element.rgb.green ^ localResult.element.rgb.green;
  291.         inkColor.element.rgb.blue = localBackground.element.rgb.blue ^ localResult.element.rgb.blue;
  292.     }
  293.     GXSetInkColor(inky, &inkColor);
  294.     GXSetInkTransfer(inky, &fastMode);
  295.     GXDisposeShape(deviceBitsShape);
  296. }
  297.  
  298. void SetShapeFastXorTransfer(gxShape source, gxColor *background, gxColor *result)
  299. {
  300.     long viewPortCount;
  301.  
  302.     viewPortCount = GXGetTransformViewPorts(GXGetShapeTransform(source), nil);
  303.     if( viewPortCount ) {
  304.         gxViewPort vp;
  305.         gxViewDevice vd;
  306.         gxInk inky;
  307.         long viewDeviceCount;
  308.         void *buffer = NewPtr( sizeof(gxViewPort) * viewPortCount );
  309.  
  310.         if (MemError()) Debugger();
  311.         GXGetTransformViewPorts(GXGetShapeTransform(source), (gxViewPort *)buffer);
  312.  
  313.         if( viewDeviceCount = GXGetViewPortViewDevices(vp = *(gxViewPort *)buffer, nil) ) {
  314.             SetPtrSize((Ptr) buffer, viewDeviceCount * sizeof(gxViewDevice));
  315.             if (MemError())
  316.             {   DisposePtr((Ptr) buffer);
  317.                 buffer = NewPtr(viewDeviceCount * sizeof(gxViewDevice));
  318.                 if (MemError()) Debugger();
  319.             }
  320.             GXGetViewPortViewDevices(vp, (gxViewDevice *)buffer);
  321.             vd = *(gxViewDevice *)buffer;
  322.         
  323.             if (GXGetInkOwners(inky = GXGetShapeInk(source)) > 1) {
  324.                 GXSetShapeInk(source, inky = GXNewInk());
  325.                 GXDisposeInk(inky);
  326.             }
  327.             SetInkFastXorTransfer(inky, vd, vp, background, result);
  328.             GXSetShapeInkAttributes(source, GXGetShapeInkAttributes(source) | gxSuppressDitherInk);
  329.         }
  330.  
  331.         DisposePtr((Ptr) buffer);
  332.     }
  333. }
  334.